package sw

import (
	"context"
	"fmt"
	"github.com/opentracing/opentracing-go"
	"github.com/uber/jaeger-client-go"
	"github.com/uber/jaeger-client-go/config"
	"io"
)

var Tracing opentracing.Tracer

// 初始化一个仅本地生成 Trace ID、不上报的 Tracer
func InitTracer(serviceName string) (opentracing.Tracer, io.Closer, error) {
	cfg := config.Configuration{
		ServiceName: serviceName,
		// 采样策略：固定采样，确保生成 Trace ID
		Sampler: &config.SamplerConfig{
			Type:  jaeger.SamplerTypeConst,
			Param: 1, // 全部采样（本地调试用）
		},
		// 禁用 Reporter（不向 Jaeger 服务器上报数据）
		Reporter: &config.ReporterConfig{
			LogSpans:                   false, // 不打印 Span 上报日志
			LocalAgentHostPort:         "",    // 清空 Agent 地址，禁用上报
			CollectorEndpoint:          "",    // 清空 Collector 地址，禁用上报
			DisableAttemptReconnecting: true,  // 禁用重连
		},
	}

	// 创建 Tracer（仅本地生成 Trace ID，不上报）
	Tracing, closer, err := cfg.NewTracer()
	if err != nil {
		return nil, nil, fmt.Errorf("初始化本地 tracer 失败: %v", err)
	}
	opentracing.SetGlobalTracer(Tracing)
	return Tracing, closer, nil
}

// 从上下文提取 Trace ID 和 Span ID（如果存在）
func Extract(ctx context.Context) (traceID, spanID string) {
	// 关键：使用 opentracing.SpanFromContext 获取 Span
	span := opentracing.SpanFromContext(ctx)
	if span == nil {
		return "", ""
	}

	// 将 OpenTracing Span 转换为 Jaeger Span，以获取 TraceID/SpanID
	jaegerSpan, ok := span.(*jaeger.Span)
	if !ok {
		return "", ""
	}

	// 提取 Trace ID 和 Span ID（转为字符串）
	traceID = jaegerSpan.SpanContext().TraceID().String()
	spanID = jaegerSpan.SpanContext().SpanID().String()
	return
}

func Tid(ctx context.Context) string {
	traceID, spanID := Extract(ctx)
	if traceID == "" {
		return ""
	}
	return traceID + "." + spanID
}
